<?php

declare(strict_types=1);

namespace think\auth\middleware;

use think\App;
use think\exception\HttpException;
use think\Response;
use think\Request;
use think\auth\model\UserModel;

/**
 * 中间件.
 */
class Auth
{
    protected App $app;

    public function __construct(App $app)
    {
        $this->app = $app;
    }

    public function handle(Request $request, \Closure $next, string $permission = '')
    {
        if ($request->method(true) == 'OPTIONS') return Response::create()->code(204);
        try {
            if (true === $this->app->get('auth.token')->Verify()) {
                $user = $this->app->get('auth.user')->Fetch();
                if (!$user) return $this->handleNotLoggedIn();

                // 路由注入
                $request->user = $user;
                // 绑定当前用户模型
                $this->app->bind(UserModel::class, $user);
                // 绑定用户后一些业务处理
                $this->bindUserAfter($request);

                //鉴权
                if(!empty($permission) && !$request->user->Can($permission)) return $this->handleNoAuthority();
                return $next($request);
            }
            return $this->handleNotLoggedIn();
        } catch (\Exception $e) {
            if ($e instanceof HttpException) {
                $code = $e->getStatusCode();
            } else {
                $code = 500;
            }
            return Response::create(['code' => $code,'message' => $e->getMessage(), 'data'=>null], 'json');
        }

    }

    /**
     * 用户未登录.
     * @return Response
     */
    public function handleNotLoggedIn(): Response
    {
        return Response::create(['code' => 401,'message' => '用户未登录', 'data'=>null], 'json');
    }

    /**
     * 没有权限.
     * @return Response
     */
    public function handleNoAuthority(): Response
    {
        return Response::create(['code' => 403,'message' => '无权访问', 'data'=>null], 'json');
    }

    public function handleTokenExpired(): Response
    {
        return Response::create(['code' => 402,'message' => '登录已过期，请重新登录', 'data'=>null], 'json');
    }

    protected function bindUserAfter($request)
    {
        // 当前用户
        // $request->user
    }
}
